package cn.newx.unit
{
	import cn.newx.unit.Events.PlayerLoadEvent;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.Timer;
	
	import mx.controls.Alert;
	
	public class Player extends Sprite
	{
		/**
		 * 构造函数
		 * 输入内容包括以下：
		 * @param playerDoc:角色素材
		 * @param width:角色的基本宽度
		 * @param height:角色的基本高度
		 */
		public function Player(player_doc:PlayerDoc,width:uint,height:uint,m:uint=2):void
		{
			playerDoc = player_doc;
			// 初始化
			myWidth=width;
			myHeight=height;
			myStep=0;
			myDirection=0;
			mySpeed=5;
			
			mode = m; // 行走模式，1为四面，2为8面
			
			myTimer=new Timer(100);
			myTimer.addEventListener(TimerEvent.TIMER,drawPlayer);

			playerDoc.addEventListener(PlayerLoadEvent.LOAD_COMPLATE,makePlayerMaps);
			playerDoc.startLoad();
		}
		
		public function set pos(_pos:Array):void
		{
			this.x = getTrueX(_pos[0]);
			this.y = getTrueY(_pos[1]);
		}
		
		/**
		 * 设置用户的名字
		 * @param n 用户要显示的名字
		 * 
		 */
		public function set playerName(n:String):void
		{
			nameShower=new TextField();
			nameShower.autoSize=TextFieldAutoSize.LEFT;
			nameShower.selectable=false;
			nameShower.text=n;
			nameShower.y=myHeight;
			nameShower.x=(myWidth-nameShower.width)/2;
			
			myName=n;
			addChild(nameShower);
			
		}
		
		/**
		 * 控制角色移动到特定的位置
		 * 在移动的过程中，根据角色的坐标来判断其正确的方向
		 * @param x 目标位置的X坐标
		 * @param y 目标位置的Y坐标
		 */
		public function moveto(x:int,y:int):void
		{
			// 计算真实距离
			// 以模拟注册点在脚下
			targetX=getTrueX(x);
			targetY=getTrueY(y);
			this.run();
		}
		
		/**
		 * 设置角色方向
		 * $param d 想要设置的角色方向
		 */
		public function set direction(d:uint):void
		{
			if(this.mode==1 && d>Player.UP) return;
			myDirection=d;
		}
		
		/**
		 * 设置角色方向for键盘及摄象机
		 * 
		 * @param d 键值
		 * @param m 模式
		 */
		public function setDirection(d:uint,m:String=''):void
		{
			var value:uint = m=='down' ? 1 : 0;
			switch(d)
			{
				case 87:
					ydirection = -1*value;
					break;
				
				case 83:
					ydirection = value;
					break;
				
				case 65:
					xdirection = -1*value;
					break;
				
				case 68:
					xdirection = value;
					break;
				
				default:break;
			}
			run();
		}
		
		
		/**
		 * 读取IO错误
		 */
		public function ioErrorHandle(e:IOErrorEvent):void
		{
			Alert("IOErrorEvent");
		}
		
		/**
		 * 调试函数，返回调试信息
		 */
		public function getDebuger():String
		{
			return myDebuger;
		}
		
		/**
		 * 运行
		 */
		private function run():void
		{
			myTimer.start();
		}
		
		
		/**
		 * 停止
		 */
		private function stop():void
		{
			try{
				myTimer.stop();
				Display(myDirection,0); // 将角色设置在当前方向的第一帧
			}catch(e:Error){
				
			}
		}
		
		/**
		 * 绘制角色
		 * 从数组中读取特定方向各动作，并循环显示形成动画
		 */		
		private function drawPlayer(e:TimerEvent):void
		{
			movePlayer();
			Display(myDirection);
		}
		
		/**
		 * 角色移动控制
		 */
		
		private function movePlayer():void
		{
			// 设置方向
			switch(xdirection)
			{
				case 1:
					switch(ydirection)
					{
						case 0: this.direction=Player.RIGHT; break;
						case 1: this.direction= this.mode == 1 ? Player.DOWN : Player.RIGHT_DOWN; break; // 4面与8面
						case -1: this.direction=this.mode == 1 ? Player.UP : Player.RIGHT_UP; break;
						default:break;
					}
					break;
				case -1:
					switch(ydirection)
					{
						case 0: this.direction=1; break;
						case 1: this.direction=this.mode == 1 ? Player.DOWN : Player.LEFT_DOWN; break;
						case -1: this.direction=this.mode == 1 ? Player.UP : Player.LEFT_UP; break;
						default:break;
					}
					break;
				
				case 0:
					switch(ydirection)
					{
						case 0: stop(); break;
						case 1: this.direction=0; break;
						case -1: this.direction=3; break;
						default:break;
					}
					break;
				default:break;
			}
		}
		
		/**
		 * 角色初始化
		 * 将角色各方向各动作加入数组中
		 */
		
		private function makePlayerMaps(e:Event):void
		{
			
			
			// 计算步数
			myStep=Math.floor(playerDoc.Data.width/myWidth);
			
			for(var i:uint=0;i<Math.floor(playerDoc.Data.height/myHeight);i++)
			{
				var arr:Array=new Array();
				for(var m:uint=0;m<myStep;m++)
				{
					var bmp_t:BitmapData=new BitmapData(myWidth,myHeight,true,0x00FFFFFF);
					bmp_t.copyPixels(playerDoc.Data,new Rectangle(myWidth*m,myHeight*i,myWidth,myHeight),new Point(0,0));
					arr.push(bmp_t);
				}
				maps.push(arr);
			}
			
			// 释放资源
			playerDoc.clear();
			// 显示
			Display(myDirection);			
		}
		
		/**
		 * 生成初始图象
		 * @param d 初始状态的方向
		 */
		private function Display(d:uint,p:uint=99):void
		{
			// 清空MAP
			if(map!=null)
			{
				this.removeChild(map);
			}
			
			map=new Bitmap(maps[d][pointer]);
			this.addChild(map);
			
			// 循环控制
			if(pointer<myStep-1)
			{
				pointer++;
			}else{
				pointer=0;
			}
			
			pointer= p==99 ? pointer : p;
		}
		
		// 根据某数值获得对应的真实x坐标偏移动
		private function getTrueX(x:int):int
		{
			return (x-myWidth/2);
		}
		
		// 根据某数值获得对应的真实x坐标偏移动
		private function getTrueY(y:int):int
		{
			return (y-myHeight);
		}
		
		/**@private */
		private var playerDoc:PlayerDoc;					// 角色文档
		private var maps:Array=new Array();					// 角色资料数组
		private var map:Bitmap;								// 显示用对象，将通过不段刷新本对象来显示动画效果
		private var myDirection:uint;						// 方向控制
		private var myLoader:Loader;						// 素材加载用Loader对象
		private var myTimer:Timer;							// 计时器，用来控制动画效果
		private var myWidth:uint;							// 角色默认宽度
		private var myHeight:uint;							// 角色默认高度
		private var myStep:uint;							// 总步数
		private var pointer:uint;							// 当前步数
		private var myDebuger:String = new String();
		private var mode:uint;
		
		/**@private */
		private var targetX:int;							// 移动的目标位置X
		private var targetY:int;							// 移动的目标位置Y
		private var mySpeed:int;							// 移动速度		
		private var targetPath:Array;						// 路径移动
		private var xdirection:int;
		private var ydirection:int;
		/**@private */
		private var myName:String;
		private var nameShower:TextField;						// 用户名显示器
		
		/**@private */
		
		public static const UP:uint = 3;
		public static const DOWN:uint = 0;
		public static const LEFT:uint = 1;
		public static const RIGHT:uint = 2;
		
		public static const LEFT_UP:uint = 6;
		public static const LEFT_DOWN:uint = 4;
		public static const RIGHT_UP:uint = 7;
		public static const RIGHT_DOWN:uint = 5;
	}
}